<?php
/* 
 * FST Migrate: use only when migrating from one account to another!
 * Abe Yang <abeyang@cal.berkeley.edu> (c) 2008
 * http://code.google.com/p/flickrsetsbytag/
 *
/* ---------------------------------------------------------------------------------- */

require('../fst.class.php');

define('FST_LOOKUPALBUMS_KEYWORD'	, 'lookup_albums');
define('FST_LOOKUPPHOTOS_KEYWORD'	, 'lookup_photos');
define('FST_BUFFER_DIR'				, 'buffer/');
define('FST_SAVECOUNT'				, 20);		// save cache for every x photos
define('FST_VERBOSE'				, true);
define('IGNORE_CACHE'				, false);

class FSTMigrate extends FST {
	var $new;
	var $lookupphotos;
	
	function FSTMigrate($cache_dir = FST_CACHE_DIR) {
		parent :: FST($cache_dir);
		
		$this->new = new phpFlickr(NEW_KEY, NEW_SECRET);
		$this->new->setToken(NEW_TOKEN);
		$this->new->auth('write');
	} // end FSTMigrate()
	
	// http://farm4.static.flickr.com/3247/2690010046_41ffa9956c_m.jpg -> array(
	//	id => 2690010046
	//	secret => 41ffa9956c (not completely correct)
	//	shared => 3247
	//	farm => 4 (not yet)
	//	size => m (not yet -- TODO!)
	//	filename => 2690010046_41ffa9956c_m.jpg
	//	)
	function photoUrlToParts($url) {
		if (!strcasecmp(substr($url, 0, 7) , 'http://')) {
			$url = substr($url, 8);			// farm4.static.flickr.com/3247/2690010046_41ffa9956c_m.jpg
		}
		$arr = explode('/', $url);
		$shared = $arr[1];					// 3247
		$filename = $arr[2];				// 2690010046_41ffa9956c_m.jpg
		$fileparts = explode('_', $filename);
		$id = $fileparts[0];				// 2690010046
		$secret = $fileparts[1];			// 41ffa9956c
		return array(
			'id' => $id, 'secret' => $secret, 'shared' => $shared, 'filename' => $filename
		);
	}
	
	// http://farm4.static.flickr.com/3247/2690010046_41ffa9956c_m.jpg -> 2690010046
	function photoUrlToId($url) {
		$parts = $this->photoUrlToParts($url);
		return $parts['id'];
	}
	
	// http://farm4.static.flickr.com/3247/2690010046_41ffa9956c_m.jpg -> 2690010046_41ffa9956c_m.jpg
	function photoUrlToFilename($url) {
		$parts = $this->photoUrlToParts($url);
		return $parts['filename'];
	}

	/* MIGRATE ALBUMS
	---------------------------------------------------------------------------------- */
	
	// grabs albums in reverse order
	function migrateSomeAlbums($start_index, $limit = 5) {
		$this->getAllAlbumsList();
		$allalbumsreverse = array_reverse($this->allalbums);
		
		$i = 0;
		$end_index = $start_index + $limit;
		foreach($allalbumsreverse as $albumname) {
			if ($i >= $start_index && $i < $end_index) {
				if (FST_VERBOSE) echo '[' . $i . '] ';
				$album = $this->getAlbum($albumname['id']);
				$this->migrateAlbum($album);
				// print_r($album);
			}
			$i++;
		}
	} // end migrateSomeAlbums()

	// returns albumid 
	// if album already exists, removes existing album and creates new one
	function migrateAlbum($old_album) {
		// grab caches
		$this->getLookupAlbums();
		$this->getLookupPhotos();
		
		$oldalbumid = $old_album['id'];
		$newalbumid = $this->lookupalbums[$oldalbumid];
		
		if (FST_VERBOSE) echo 'grabbing old album: ' . $oldalbumid . '<br />';
		
		if ($newalbumid && FST_VERBOSE) {
			echo 'album exists: deleting album, then creating new one...<br />';
			$this->new->photosets_delete($newalbumid);
		}

		else if (!$newalbumid && FST_VERBOSE) echo 'album does not exist!: creating album and grabbing photos.. <br />';
			
		// grab primary photo 
		// (it's lame that we have to cycle thru each photo to find it, I know)
		$oldprimaryid = $old_album['primary'];
		foreach($old_album['photo'] as $photo) {
			if ($photo['isprimary']) {
				$primaryphoto = $photo;
				break;
			}
		}
		
		// create new directory based on setif (if it doesn't already exist)
		$dir = $this->checkAndCreateDirectory($oldalbumid);
		
		// upload primary photo (necessary prereq before creating a new album)
		$newprimaryid = $this->migratePhoto($primaryphoto, $dir);
		$this->setLookupPhotos();	// save primary to cache
		
		// create album
		$newalbum = $this->new->photosets_create($old_album['title'], $old_album['description'], $newprimaryid);
		$newalbumid = $newalbum['id'];
		if (FST_VERBOSE) echo 'new album: ' . $newalbumid . '<br />';
		
		// save album to cache (save it now in case of crash)
		$this->lookupalbums[$oldalbumid] = $newalbumid;
		$this->setLookupAlbums();
		
		
		// cycle through photos
		$i = 0;
		foreach($old_album['photo'] as $photo) {
			// if photo is a primary, skip it -- primary already in album
			if (!$photo['isprimary']) {
				// upload photo to flickr
				$photoid = $this->migratePhoto($photo, $dir);
				// add photo to album
				$this->new->photosets_addPhoto($newalbumid, $photoid);
				// save photos to cache every once in a while
				if (!(++$i % FST_SAVECOUNT)) $this->setLookupPhotos();
			}
		}
		
		$this->setLookupPhotos();	// save photos to cache
		
		return $newalbumid;
	} // end migrateAlbum()
	
	/* MIGRATE PHOTOS
	---------------------------------------------------------------------------------- */
	
	// prereq: getLookupPhotos() has been called already
	// must feed photo object
	// returns photoid (if photo already exists, simply grabs id from lookup)
	function migratePhoto($old_photo, $dir = FST_BUFFER_DIR) {
		$oldphotoid = $old_photo['id'];
		$newphotoid = $this->lookupphotos[$oldphotoid];
		
		if ($newphotoid && !IGNORE_CACHE) {
			if (FST_VERBOSE) echo 'photo exists: no need to upload <br />';
		}
		else {
			if (FST_VERBOSE) echo 'photo ' . $oldphotoid . ' does not exist!: uploading.. <br />';
			
			$photourl = $this->photoUrl($old_photo, 'o');
			/* sync_upload:
				Photo: The path of the file to upload.
			    Title: The title of the photo.
			    Description: A description of the photo. May contain some limited HTML.
			    Tags: A space-separated list of tags to apply to the photo.
			    is_public: Set to 0 for no, 1 for yes.
			    is_friend: Set to 0 for no, 1 for yes.
			    is_family: Set to 0 for no, 1 for yes.
			*/
//			if (FST_VERBOSE) echo "$photourl <br />";

			$filename = $this->getImage($photourl, $dir);
			$newphotoid = $this->new->sync_upload($filename, $old_photo['title'], $old_photo['description'], $old_photo['tags'], 1, 1, 1);

			// save relationship to lookup
			$this->lookupphotos[$oldphotoid] = $newphotoid;
			
		}
		
		return $newphotoid;
		
	} // end migratePhoto()
	
	/* DIRECTORY HANDLING
	---------------------------------------------------------------------------------- */
	
	// prereq: directory is created already
	function getImage($url, $dir = FST_BUFFER_DIR) {
		if (!$url) {
			echo "ERROR: url not specified";
			break;
		}
		$image = file_get_contents($url);
		$filename = $dir . $this->photoUrlToFilename($url);
		$fp = fopen($filename, 'w'); 
		fwrite($fp, $image); 
		fclose($fp);
		return $filename;
	} // end getImage()
	
	// if directory based on set id does not exist, create it. returns dir path
	function checkAndCreateDirectory($setid) {
		$dir = FST_BUFFER_DIR . $setid . '/';
		if (!is_dir($dir)) mkdir($dir);
		return $dir;
	} // end checkAndCreateDirectory()
	
	// clears contents of buffer directory, but does not remove the dir itself
	function clearBufferDirectory() {
		$d = dir(FST_BUFFER_DIR); 
		while($entry = $d->read()) { 
		 if ($entry!= "." && $entry!= "..") { 
		 unlink($entry); 
		 } 
		} 
		$d->close(); 
	} // end clearBufferDirectory()
	
	
	/* PHOTOS LOOKUP (CACHE)
		array(
			old_photoid1 => new_photoid1,
			old_photoid2 => new_photoid2,
			...
		)
	---------------------------------------------------------------------------------- */
	
	function displayLookupPhotos() {
		$this->getLookupPhotos();
		print_r($this->lookupphotos);
	} // end displayLookupPhotos()

	function getLookupPhotos() {
		if (!$this->lookupphotos) {
			$this->lookupphotos = $this->load(FST_LOOKUPPHOTOS_KEYWORD);
		}
		// if $this->lookupphotos still null, create an array
		if (!$this->lookupphotos) $this->lookupphotos = array();
	} // end getLookupPhotos()
	
	// saves lookupphotos (should be in memory) to cache
	function setLookupPhotos() {
		$this->save($this->lookupphotos, FST_LOOKUPPHOTOS_KEYWORD);
		if (FST_VERBOSE) echo 'saving lookupphotos<br/>';
	} // end setLookupPhotos()
	
	/* ALBUMS LOOKUP (CACHE)
	---------------------------------------------------------------------------------- */
	
	function displayLookupAlbums() {
		$this->getLookupAlbums();
		print_r($this->lookupalbums);
	} // end displayLookupAlbums()

	function getLookupAlbums() {
		if (!$this->lookupalbums) {
			$this->lookupalbums = $this->load(FST_LOOKUPALBUMS_KEYWORD);
		}
		// if $this->lookupalbums still null, create an array
		if (!$this->lookupalbums) $this->lookupalbums = array();
	} // end getLookupAlbums()
	
	// saves lookupalbums (should be in memory) to cache
	function setLookupAlbums() {
		$this->save($this->lookupalbums, FST_LOOKUPALBUMS_KEYWORD);
		if (FST_VERBOSE) echo 'saving lookupalbums<br/>';
	} // end setLookupAlbums()

} // end FSTExtension
?>

